<?php
/**
 * @desc
 * @author: jintao
 * @since: 2016/7/20
 */
class erpapi_shop_matrix_taobao_request_finance extends erpapi_shop_request_finance
{
    const _APP_NAME = 'ome';

    public function sync_bills_book_get($account_id,$start_time,$end_time,$journal_types = '',$page_no = 1,$page_size = 40){
        $rs = array('rsp'=>'fail','msg'=>'','msg_code'=>'','msg_id'=>'','data'=>'');

        //$api_name = 'store.bill.book.bills.get';

        $params = array(
            'account_id' => $account_id,
            'start_time' => $start_time,
            'end_time'   => $end_time,
            'page_no'    => $page_no,
            'page_size'  => $page_size,
        );
        if ($journal_types) {
            $params['journal_types'] = $journal_types;
        }

        $title = '店铺[' . $this->__channelObj->channel['name'] . ']获取虚拟账户明细数据';

        $logModel = app::get(self::_APP_NAME)->model('api_log');
        $log_id = $logModel->gen_id();
        $logModel->write_log($log_id,$title,get_class($this->__caller),'call',array(SHOP_BILL_BOOK_BILL_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id']),'','request','running');

        //$result = $this->_caller->call($api_name,$params,$this->shop['shop_id'],10);
        $result = $this->__caller->call(SHOP_BILL_BOOK_BILL_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id']);

        if ($result['res_ltype'] > 0) {
            for ($i=0;$i<3;$i++) {
                $result = $this->__caller->call(SHOP_BILL_BOOK_BILL_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id']);
                if ($result['res_ltype'] == 0) {
                    break;
                }
            }
        }
        $rs['msg_id'] = $result['msg_id'];

        // 记日志
        $api_status = $result['rsp'] != 'succ' ? 'fail' : 'success';
        $logData = array(
            'msg_id' => $result['msg_id'],
            'status' => $api_status,
        );
        $logModel->update($logData,array('log_id'=>$log_id));

        if ($rsp['rsp'] == 'succ') {
            $rs['msg'] = $result['err_msg'];
            return $rs;
        } elseif ($result['rsp'] !== 'succ') {
            $rs['msg'] = '请求失败';
            return $rs;
        }

        $rs['rsp']  = 'succ';
        $rs['data'] = json_decode($result['data'],true);
        return $rs;
    }

    /**
     * undocumented function
     *
     * @return void
     * @author
     **/
    public function bills_book_get($account_id,$start_time,$end_time,$journal_types = '',$page_no = 1,$page_size = 40)
    {
        $rs = array('rsp'=>'fail','msg'=>'','msg_code'=>'','msg_id'=>'','data'=>'');

        //$api_name = 'store.bill.book.bills.get';

        $params = array(
            'account_id' => $account_id,
            'start_time' => $start_time,
            'end_time'   => $end_time,
            'page_no'    => $page_no,
            'page_size'  => $page_size,
        );
        if ($journal_types) {
            $params['journal_types'] = $journal_types;
        }

        $title = '店铺[' . $this->shop['name'] . ']获取虚拟账户明细数据';
        $callback = array(
            'class' => get_class($this),
            'method' => 'bills_book_get_callback',
            'params' => $params
        );

        //$return = $this->_caller->request(SHOP_BILL_BOOK_BILL_GET,$params,$callback,$title,$this->shop['shop_id'],10,false);
        $result = $this->__caller->call(SHOP_BILL_BOOK_BILL_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id']);

        $rs['rsp'] = 'succ';
        return $rs;
    }

    /**
     * undocumented function
     *
     * @return void
     * @author
     **/
    public function bills_book_get_callback($response, $callback_params)
    {
        $status          = $response['rsp'];
        $data            = @json_decode($response['data'],true);
        $request_params  = $callback_params['params'];

        if ($status= 'succ' && $data['bills']['book_bill']) {
            $funcObj = kernel::single('finance_func');

            $shop = $funcObj->getShopByShopID($callback_params['shop_id']);

            $bookbillModel = app::get('finance')->model('analysis_book_bills');

            // 数据保存
            foreach ($data['bills']['book_bill'] as $bill) {
                $exist = $bookbillModel->getList('book_bill_id',array('bid'=>$bill['bid'],'shop_id' => $shop['shop_id']),0,1);
                if ($exist) { continue;}

                $bookbills[] = array(
                    'bid'                 => $bill['bid'],
                    'account_id'          => $bill['account_id'],
                    'journal_type'        => $bill['journal_type'],
                    'amount'              => bcdiv($bill['amount'], 100,3),
                    'book_time'           => strtotime($bill['book_time']),
                    'description'         => $bill['description'],
                    'gmt_create'          => strtotime($bill['gmt_create']),
                    // 'taobao_alipay_id' => ,
                    // 'other_alipay_id'  => ,
                    'shop_id'             => $shop['shop_id'],
                    'shop_type'           => $shop['shop_type'],
                    'fee_item_id'         => $this->get_fee_item($bill['account_id']),
                );
            }

            if ($bookbills) {
                $sql = ome_func::get_insert_sql($bookbillModel,$bookbills);
                $bookbillModel->db->exec($sql);
            }

            if ($data['has_next'] == true) {
                // 放队列
                $worker = 'finance_cronjob_execQueue.book_bills_get';
                $params = $request_params;
                $params['page_no'] += 1;
                $params['shop_id'] = $shop['shop_id'];

                $log_title = '请求获取虚拟账户明细:'.$params['start_time'].'至'.$params['end_time'].'';
                $funcObj->addTask($log_title,$worker,$params,$type='slow');
            }
        }
        return $this->callback($response, $callback_params);
    }

    private function get_fee_item($outer_id)
    {
        static $fee_item;

        if ($fee_item[$outer_id]) {
            return $fee_item[$outer_id];
        }

        $feeItemModel = app::get('finance')->model('bill_fee_item');

        $feeItem = $feeItemModel->getList('fee_item_id',array('outer_account_id'=>$outer_id,'channel' => 'tmall'),0,1);

        $fee_item[$outer_id] = $feeItem[0]['fee_item_id'];

        return $fee_item[$outer_id];
    }

    /**
     * 费用明细
     *
     * @return void
     * @author
     **/
    public function bills_get($start_time,$end_time,$page_no=1,$page_size=40,$time_type='')
    {
        $rs = array('rsp'=>'fail','msg'=>'','msg_code'=>'','msg_id'=>'','data'=>'');

        $denytime = array(
            0 => array(mktime(9,30,0,date('m'),date('d'),date('Y')),mktime(11,0,0,date('m'),date('d'),date('Y'))),
            1 => array(mktime(14,0,0,date('m'),date('d'),date('Y')),mktime(17,0,0,date('m'),date('d'),date('Y'))),
            2 => array(mktime(20,0,0,date('m'),date('d'),date('Y')),mktime(22,30,0,date('m'),date('d'),date('Y'))),
            2 => array(mktime(1,0,0,date('m'),date('d'),date('Y')),mktime(3,0,0,date('m'),date('d'),date('Y'))),
        );

        $now = time();
        foreach ($denytime as $value) {
            if ($value[0]<=$now && $now<=$value[1]) {
                $rs['msg'] = 'deny time';
                // return $rs;
            }
        }

        //$api_name = 'store.bills.get';

        $params = array(
            'start_time' => $start_time,
            'end_time' => $end_time,
            'page_no' => $page_no,
            'page_size' => $page_size,
            'time_type' => $time_type,
        );

        $title = '店铺[' . $this->shop['name'] . ']获取账单明细';
        $logModel = app::get(self::_APP_NAME)->model('api_log');
        $log_id = $logModel->gen_id();
        $logModel->write_log($log_id,$title,get_class($this->_caller),'call',array(SHOP_BILL_BILL_GET,$params,$this->shop['shop_id'],10),'','request','running');

        //$result = $this->_caller->call(SHOP_BILL_BILL_GET,$params,$this->shop['shop_id'],10);
        $result = $this->__caller->call(SHOP_BILL_BOOK_BILL_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id']);

        if ($result['res_ltype'] > 0) {
            for ($i=0;$i<3;$i++) {
                //$result = $this->_caller->call(SHOP_BILL_BILL_GET,$params,$this->shop['shop_id'],10);
                $result = $this->__caller->call(SHOP_BILL_BOOK_BILL_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id']);
                if ($result['res_ltype'] == 0) {
                    break;
                }
            }
        }
        $rs['msg_id'] = $result['msg_id'];

        // 记日志
        $api_status = $result['rsp'] != 'succ' ? 'fail' : 'success';
        $logData = array(
            'msg_id' => $result['msg_id'],
            'status' => $api_status,
        );
        $logModel->update($logData,array('log_id'=>$log_id));

        if ($result['rsp'] !== 'succ') {
            $rs['msg'] = $result['err_msg'];
            return $rs;
        } else{
            $rs['msg'] = '请求失败';
            return $rs;
        }

        $rs['rsp']  = 'succ';
        $rs['data'] = json_decode($result['data'],true);
        return $rs;
    }

    /**
     * 实时获取[支付宝]交易记录
     * @access public
     * @param String $shop_id 店铺ID
     * @param String $shop_name 店铺名称
     * @param String $start_time 开始时间
     * @param String $end_time 结束时间
     * @param Int $page 当前请求页码
     * @param Int $limit 每页请求数量
     */
    public function trade_search($shop_id,$shop_name,$start_time,$end_time,$page=1,$limit=100){
        $rs = array('rsp'=>'fail','msg'=>'','msg_code'=>'','msg_id'=>'','data'=>'');
        if (empty($shop_id) || empty($start_time) || empty($end_time)){
            $rs['msg'] = 'shop_id,start_time,end_time不能为空';
            return $rs;
        }

        $params = array(
            'order_status' => 'ACC_FINISHED',#TODO:不获取交易数据，即在线支付的,交易数据交由任务号接口获取，如果不指定,则只能在程序段进行过滤
            'start_time' => $start_time,
            'end_time' => $end_time,
            'page_no' => $page,
            'page_size' => $limit,
        );
        // $method = 'store.user.trade.search';
        $callback = array();//实时接口不需要设置
        $log_title = '获取[支付宝]交易记录:'.$start_time.'至'.$end_time;
        $write_log['log_type'] = 'store.trade.iostock';
        $write_log['log_title'] = $log_title;
        //$result = $this->funcObj->request($method,$params,$callback,$log_title,$shop_id,$time_out=30,$queue=false,$addon='',$write_log,$mode='sync');
        $result = $this->__caller->call(SHOP_USER_TRADE_SEARCH,$params,$callback,$title,10,$this->__channelObj->channel['shop_id'],$write_log);

        #错误代码：w01001 为时间跨度不能超过7天
        $rs['rsp'] = $result['rsp'] == 'success' ? 'succ' : $result['rsp'];
        $rs['msg'] = $result['err_msg'];
        $rs['msg_code'] = $result['err_code'];
        $rs['msg_id'] = $result['msg_id'];

        //log
        $apiLogObj = app::get('ome')->model('api_log');
        $apiLog_id = $apiLogObj->gen_id();
        $apiLog_title = '店铺['.$shop_name.']实时获取账单明细';
        $apiLogObj->write_log($apiLog_id,$apiLog_title,'finance_cronjob_execQueue','trade_search',array('store.user.trade.search',$params,$shop_id,30),'','request','running');
        $apiLog_arr['status'] = $rs['rsp'] == 'succ' ? 'success' : 'fail';
        $apiLog_arr['msg_id'] = $result['msg_id'];
        $apiLogObj->update($apiLog_arr,array('log_id'=>$apiLog_id));

        if (isset($result['data']) && $result['data']){
            $data = $result['data']['alipay_user_trade_search_response'];
            $rs['data'] = array(
                'total_results' => $data['total_results'],
                'total_pages' => $data['total_pages'],
                'total_records'  => $data['trade_records']['trade_record'],//交易记录列表
            );
        }else{
            $rs['data'] = array();
        }
        return $rs;
    }

    /**
     * 获取[支付宝]交易记录任务结果
     * @access public
     * @param String $shop_id 店铺ID
     * @param String $task_id 任务号
     */
    public function trade_taskresult_get($shop_id,$task_id){
        $rs = array('rsp'=>'fail','msg'=>'','msg_code'=>'','msg_id'=>'','data'=>'');
        if (empty($shop_id) || empty($task_id)){
            $rs['msg'] = 'shop_id,task_id不能为空';
            return $rs;
        }

        $params = array(
            'task_id' => $task_id,
        );
        //$method = 'store.topats.result.get';
        $callback = array();//实时接口不需要设置
        $log_title = '获取[支付宝]交易记录任务号('.$task_id.')结果';
        $write_log['log_type'] = 'store.trade.iostock';
        $write_log['log_title'] = $log_title;
        //$result = $this->funcObj->request($method,$params,$callback,$log_title,$shop_id,$time_out=30,$queue=false,$addon='',$write_log,$mode='sync');
        $result = $this->__caller->call(SHOP_TOPATS_RESULT_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id'],$write_log);

        if ($result['err_code'] == 'w01001'){#异步任务结果为空
            $result['rsp'] = 'success';
        }elseif (in_array($result['err_code'],array('w01151','w01136'))){
            #w01136:无效的任务号  w01151:任务号过期
            $result['rsp'] = 'success';
            $result['err_code'] = 'expired';
        }
        $rs['rsp']      = $result['rsp'] == 'success' ? 'succ' : $result['rsp'];
        $rs['msg']      = $result['err_msg'];
        $rs['msg_code'] = $result['err_code'];
        $rs['msg_id']   = $result['msg_id'];
        if (isset($result['data']) && $result['data']){
            $data = $result['data']['topats_result_get_response']['task'];
            $rs['data'] = array(
                'download_url' => $data['download_url'],
                'task_id' => $data['task_id'],
                'status' => $data['status'],
                'created' => $data['created']
            );
        }else{
            $rs['data'] = array();
        }
        return $rs;
    }

    /**
     * 获取[支付宝]交易记录任务号
     * @access public
     * @param String $shop_id 店铺ID
     * @param String $start_time 开始时间
     * @param String $end_time 结束时间
     */
    public function trade_taskid_get($shop_id,$start_time,$end_time){
        $rs = array('rsp'=>'fail','msg'=>'','msg_code'=>'','msg_id'=>'','data'=>'');
        if (empty($shop_id) || empty($start_time) || empty($end_time)){
            $rs['msg'] = 'shop_id,start_time,end_time不能为空';
            return $rs;
        }

        $params = array(
            'fields' => 'create_time,type,business_type,balance,in_amount,out_amount,alipay_order_no,merchant_order_no,self_user_id,opt_user_id,memo',
            'start_time' => $start_time,
            'end_time' => $end_time,
            'type' => 'CHARGE,TRANSFER',#只获取在线支付(即交易)和信用卡手续费
        );
        //$method = 'store.topats.user.accountreport.get';
        $callback = array();//实时接口不需要设置
        $log_title = '获取[支付宝]交易记录任务号:'.$start_time.'至'.$end_time;
        $write_log['log_type'] = 'store.trade.iostock';
        $write_log['log_title'] = $log_title;
        //$result = $this->funcObj->request($method,$params,$callback,$log_title,$shop_id,$time_out=30,$queue=false,$addon='',$write_log,$mode='sync');
        $result = $this->__caller->call(SHOP_TOPATS_USER_ACCOUNTREPORT_GET,$params,$callback,$title,10,$this->__channelObj->channel['shop_id'],$write_log);

        #错误编码：w01160  参数start_time必须为前1个月以内
        $rs['rsp']      = $result['rsp'] == 'success' ? 'succ' : $result['rsp'];
        $rs['msg']      = $result['err_msg'];
        $rs['msg_code'] = $result['err_code'];
        $rs['msg_id']   = $result['msg_id'];
        if (isset($result['data']) && $result['data']){
            $data = $result['data']['alipay_topats_user_accountreport_get_response']['task'];
            $rs['data'] = array(
                'task_id' => $data['task_id'],
                'created' => $data['created'],
            );
        }else{
            $rs['data'] = array();
        }
        return $rs;
    }

    #获取退款凭证
    public function getRefundMessage($refundinfo){
        if (!$refundinfo['refund_bn']) return false;
        $params = array(
            'refund_id'=>  $refundinfo['refund_bn'],
        );
        $title = '获取店铺退款凭证';
        $result = $this->__caller->call(SHOP_GET_REFUND_MESSAGE, $params, array(), $title, 10, $refundinfo['refund_bn']);
        if($result['data']) {
            $result['data'] = json_decode($result['data'], true);
        }
        return $result;
    }

    public function addRefundMemo($refundinfo){
        $orderModel = app::get('ome')->model('orders');
        $order = $orderModel->dump($refundinfo['order_id'], 'order_bn');
        $params = array();
        $params['refund_id'] = $refundinfo['refund_apply_bn'];
        $params['content'] = $refundinfo['content'];
        $params['image'] = $refundinfo['imagebinary'];
        $callback = array(
            'class' => get_class($this),
            'method' => 'callback',
        );
        $title = '店铺('.$this->__channelObj->channel['name'].')添加[退款留言]'.'(订单号:'.$order['order_bn'].'退款单号:'.$refundinfo['refund_apply_bn'].')';;
        $rs = $this->__caller->call(SHOP_ADD_REFUND_MESSAGE,$params,$callback,$title,10,$order['order_bn']);
        return $rs;
    }

    #单拉获取退款单详情
    public function getRefundDetail($refund_id ,$refund_phase,$tid) {
        $params = array();
        $params['refund_id'] = $refund_id;
        $params['refund_phase'] = $refund_phase;
        $params['tid'] = $tid;
        $title = "店铺(".$this->__channelObj->channel['name'].")获取前端店铺".$tid."的退款单详情";
        $rsp = $this->__caller->call(SHOP_GET_TRADE_REFUND_RPC,$params,array(),$title,10,$tid);
        if($rsp['data']) {
            $rsp['data'] = json_decode($rsp['data'], true);
        }
        return $rsp;
    }

    protected function _updateRefundApplyStatusApi($status){
        $api_method = '';
        switch($status){
            case '3':
                $api_method = SHOP_REFUSE_REFUND;
                break;
        }
        return $api_method;
    }

    protected function _updateRefundApplyStatusParam($refund,$status){
        $oRefund_taobao = app::get('ome')->model('refund_apply_taobao');
        $refundData = $oRefund_taobao->getList('oid',array('refund_apply_bn'=>$refund['refund_apply_bn']), 0, 1);
        $refundRow = $refundData[0];
        $params = array(
            'refund_id'  =>$refund['refund_apply_bn'],
            'refuse_proof'=>$refund['refuse_proof'],
            'refuse_message'=>$refund['refuse_message'],
        );
        if ($status == '3') {#退款单拒绝
            $params['oid'] = $refundRow['oid'];
        }
        return $params;
    }
}